#include "cacheAlloc.h"
#include <thread>

 
void BenchmarkMalloc(size_t ntimes, size_t nworks, size_t rounds)
{
	std::vector<std::thread> vthread(nworks);
	size_t malloc_costtime = 0;
	size_t free_costtime = 0;
 
	for (size_t k = 0; k < nworks; ++k)
	{
		vthread[k] = std::thread([&, k]() {
			std::vector<void*> v;
			v.reserve(ntimes);
 
			for (size_t j = 0; j < rounds; ++j)
			{
				size_t begin1 = clock();
				for (size_t i = 0; i < ntimes; i++)
				{
					v.push_back(malloc(16));
				}
				size_t end1 = clock();
 
				size_t begin2 = clock();
				for (size_t i = 0; i < ntimes; i++)
				{
					free(v[i]);
				}
				size_t end2 = clock();
				v.clear();
 
				malloc_costtime += end1 - begin1;
				free_costtime += end2 - begin2;
			}
		});
	}
 
	for (auto& t : vthread)
	{
		t.join();
	}
 
	printf("%u个线程并发执行%u轮次，每轮次malloc %u次: 花费：%u ms\n",
		nworks, rounds, ntimes, malloc_costtime);
 
	printf("%u个线程并发执行%u轮次，每轮次free %u次: 花费：%u ms\n",
		nworks, rounds, ntimes, free_costtime);
 
	printf("%u个线程并发malloc&free %u次，总计花费：%u ms\n",
		nworks, nworks*rounds*ntimes, malloc_costtime + free_costtime);
}
 
 
// 单轮次申请释放次数 线程数 轮次
void BenchmarkConcurrentMalloc(size_t ntimes, size_t nworks, size_t rounds)
{
	std::vector<std::thread> vthread(nworks);
	size_t malloc_costtime = 0;
	size_t free_costtime = 0;
 
	for (size_t k = 0; k < nworks; ++k)
	{
		vthread[k] = std::thread([&]() {
			std::vector<void*> v;
			v.reserve(ntimes);
 
			for (size_t j = 0; j < rounds; ++j)
			{
				size_t begin1 = clock();
				for (size_t i = 0; i < ntimes; i++)
				{
					//void* ptr = cAlloc(16);
					//std::cout << "alloc: " << ptr << std::endl;

					v.push_back(cAlloc(16));
				}
				size_t end1 = clock();
 
				size_t begin2 = clock();
				for (size_t i = 0; i < ntimes; i++)
				{
					//std::cout << "free: " << v[i] << std::endl;
					cFree(v[i]);
				}
				size_t end2 = clock();
				v.clear();
 
				malloc_costtime += end1 - begin1;
				free_costtime += end2 - begin2;
			}
		});
	}
 
	for (auto& t : vthread)
	{
		t.join();
	}
 
	printf("%u个线程并发执行%u轮次，每轮次concurrent alloc %u次: 花费：%u ms\n",
		nworks, rounds, ntimes, malloc_costtime);
 
	printf("%u个线程并发执行%u轮次，每轮次concurrent dealloc %u次: 花费：%u ms\n",
		nworks, rounds, ntimes, free_costtime);
 
	printf("%u个线程并发concurrent alloc&dealloc %u次，总计花费：%u ms\n",
		nworks, nworks*rounds*ntimes, malloc_costtime + free_costtime);
}
 
int main()
{
	std::cout << "==========================================================" << std::endl;
	BenchmarkMalloc(10000, 4, 100);
	std::cout << std::endl << std::endl;
 
	BenchmarkConcurrentMalloc(10000, 4, 100);
	std::cout << "==========================================================" << std::endl;
 
	//system("pause");
	return 0;
}

//g++ testcache.cpp cacheThread.cpp cacheCentral.cpp cachePage.cpp cacheObjectPool.cpp logger.cpp -o cachemain -std=c++11 -llog4cxx -g

// int main()
// {
//     int* p = reinterpret_cast<int*>(cAlloc(sizeof(int)));
//     *p = 1;
//     std::cout << p << ":" << *p << std::endl;

//     int *p1 = reinterpret_cast<int*>(cAlloc(sizeof(int)));
//     std::cout << p1 << ":" << *p1 << std::endl;
//     int *p2 = reinterpret_cast<int*>(cAlloc(sizeof(int)));
//     std::cout << p2 << ":" << *p2 << std::endl;
//     int *p3 = reinterpret_cast<int*>(cAlloc(sizeof(int)));
//     std::cout << p3 << ":" << *p3 << std::endl;

//     qSpan* sp = reinterpret_cast<qSpan*>(cAlloc(sizeof(qSpan)));
//     std::cout << sp << std::endl;

    
//     qSpan* sp1 = reinterpret_cast<qSpan*>(cAlloc(sizeof(qSpan)));
//     std::cout << sp1 << std::endl;

    
//     qSpan* sp2 = reinterpret_cast<qSpan*>(cAlloc(sizeof(qSpan)));
//     std::cout << sp2 << std::endl;

    
//     // qSpan* sp3 = reinterpret_cast<qSpan*>(cAlloc(sizeof(qSpan)));
//     // std::cout << sp3 << std::endl;

//     cFree(p);
//     cFree(p1);
//     cFree(p2);


//     return 0;
// }